package reservation;
import inputOutput.*;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.io.IOException;

import config.Config;
import ecole.infrastructure.*;
import ecole.organisation.Seance;
import ecole.utilisateur.Professeur;

/**
 * Classe Reservation : permet d'effectuer une réservation
 * 
 * @author Hadrien Luttiau
 */
public class Reservation implements java.io.Serializable{
	private static final long serialVersionUID = -6604001388514624340L;

	private static List<Reservation> listeReservation = new ArrayList<Reservation>();
	private static int typeSave = Config.TYPE_SAUVEGARDE;

	private Professeur professeur;
	private Seance seance;
	private Salle salle;
	private boolean etatResa = false;
	private Calendar calDate = null;
	private String tabCreneaux[] = {"8H à 10H","10H15 à 12H15", "13H30 à 15H30", "15H45 à 17H45"};

	/**
	 * Créer un carnet de réservations vide
	 */
	public Reservation () {}
	
	public Reservation (Professeur prof)
	{
		this.professeur = prof;
	}
	public Reservation (Professeur prof, Salle salle, Seance seance)
	{
		this.professeur = prof;
		this.salle = salle;
		this.seance = seance;
	}

	
	/**
	 * Permet d'effectuer une réservation
	 * 
	 * @param nomSaisi : Le nom de l'utilisateur
	 * @param typeSalleSaisi : Le type de la salle
	 * @param dateSaisie : La date pour laquelle l'utilisateur veut r�server
	 * @param creneauSaisi : Le cr�neau horaire a reserver
	 * @param effectifSaisi : L'effectif voulu
	 * @param Batiment.listeBatiment : Le batiment contenant la salle � r�server
	 * @throws IOException 
	 */
	public static boolean reserver(Professeur prof, Seance seance,  int typeSalle) {
		Salle salleTrouve = null;
		

		try {
			int i = 0;
			while ((i < Batiment.listeBatiment.size()) && (salleTrouve == null)) {
				salleTrouve = Batiment.listeBatiment.get(i).rechercher(typeSalle ,seance.getDate(), seance.getCreneau());				// Rechercher une salle libre
				i++;
			}
		} catch(Exception e) {
			System.out.println("Plus de salles disponibles (exception) !");
		}

		if (salleTrouve == null) {															// V�rifier si une salle est retourn�e
			System.out.println("Plus de salles disponibles ! (if) ");						// Si elle ne l'est pas, afficher un message d'erreur
			return false;
		}
		else 
		{																					// Si une salle est retourn�e
			Reservation r = new Reservation(prof,salleTrouve,seance);
			if (listeReservation.isEmpty()) 												// Vérifier si la liste de réservations est vide
			{
				listeReservation.add(r);													// Si elle l'est, ajouter la réservation
				
					sauvegarde();
				
				return true;
			} 
			else
			{
				for ( Reservation res: listeReservation )
				{
					if ( res.equals(r))
					{
						System.out.println("Cette reservation existe déja !");
						return false;
					}
					else
					{
						
					}
				}
				listeReservation.add(r);
				sauvegarde();
				return true;
			}
		}
	}

	private static void sauvegarde() {
		Serialisation serial ;
		if(typeSave == 0 || typeSave == 2)
		{
			serial = new SerialisationBinaire();
			try {
				serial.sauvegarder(listeReservation);
			} catch (IOException e) {
				e.printStackTrace();
			}
			}
		if(typeSave == 1 || typeSave == 2)
		{
			serial = new SerialisationTexte();
			try {
				serial.sauvegarder(listeReservation);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public boolean equals(Object o)
	{
		if( o instanceof Reservation)
			return false;
		else
		{
			Reservation resa = (Reservation) o;
			if( resa.getSalle().equals(this.salle))
				return false;
			if(resa.calDate.getTime() != this.calDate.getTime())
				return false;
			if( resa.seance.getCreneau() != this.seance.getCreneau())
				return false;
			return true;
		}
	}

	/**
	 * Permet d'effectuer une meme réservation sur plusieurs semaines
	 * 
	 * @param nomSaisi : Le nom de l'utilisateur
	 * @param typeSalleSaisi : Le type de la salle
	 * @param dateSaisie : La date pour laquelle l'utilisateur veut r�server
	 * @param creneauSaisi : Le cr�neau horaire � r�server
	 * @param effectifSaisi : L'effectif voulu
	 * @param Batiment.listeBatiment : Le batiment contenant la salle � r�server
	 * @param nbSemaines : Le nombre de semaines pour lesquelles l'utilisateur veut effectuer sa r�servation
	 * @throws IOException 
	 */
	public void reserverSemaines(Professeur prof, Seance seance, int typeSalle, int nbSemaines){
		for (int i=0; i<nbSemaines; i++) {
			calDate.add(Calendar.DATE,7);
			reserver(prof, seance, typeSalle);
		}
	}

	/**
	 * Permet d'effectuer une meme réservation sur plusieurs créneaux
	 * 
	 * @param nomSaisi : Le nom de l'utilisateur
	 * @param typeSalleSaisi : Le type de la salle
	 * @param dateSaisie : La date pour laquelle l'utilisateur veut r�server
	 * @param creneauSaisi : Le cr�neau horaire � r�server
	 * @param effectifSaisi : L'effectif voulu
	 * @param Batiment.listeBatiment : Le batiment contenant la salle � r�server
	 * @param nbCreneaux : Les cr�neaux pour lesquelles l'utilisateur veut effectuer sa r�servation
	 * @throws IOException 
	 */
	public void reserverCreneaux(Professeur prof, Seance seance, int typeSalle, String creneaux){
		String tabCreneauxSaisis[] = creneaux.split(",");
		int creneauInt;
		for (int i=0; i<tabCreneauxSaisis.length; i++) 
		{
			creneauInt = Integer.parseInt(tabCreneauxSaisis[i]) ;
			Seance s = new Seance(seance.getEns(), prof, seance.getDate(), creneauInt,seance.getGroupe());
			reserver(prof, s, typeSalle);
		}
	}

	/**
	 * Affiche toutes les r�servations effectu�es par un utilisateur
	 * @param nomSaisi : le nom de l'utilisateur 
	 * @return la liste des r�servations effectu�es par l'utilisateur
	 */
	public void afficherMesReservations(Professeur profSaisi) {
		if (listeReservation.isEmpty() || profSaisi == null) {
			System.out.println("Vous n'avez pas encore effectué de réservations.");
		} else {
			System.out.println("\n");
			System.out.println("****************************************************");
			System.out.println("***************** Mes réservations *****************");
			System.out.println("****************************************************");

			for ( Reservation resa : listeReservation)
			{
				if ( resa.getProfesseur().equals(profSaisi))
					System.out.println("- le "+resa.getSeance().getDate()+" de "+resa.getSeance().getCreneau()+" : Salle "+resa.getSalle().getId());
			}
			System.out.println("\n");
		}
	}

	/**
	 * Affiche une confirmation pour une unique réservation
	 * @return une confirmation pour une unique réservation
	 */
	/*public void afficherConfirmationSimple() {
		System.out.println("\n"+ getProfesseur().getNom() +", votre r�servation a bien �t� effectu�e.\n");
		System.out.println("Récapitulatif de votre réservation :");
		System.out.println("- le "+this.getSeance().getDate()+" de "+this.getSeance().getCreneau()+" : Salle "+this.getSalle().getId());
	}*/

	/**
	 * Affiche une confirmation pour plusieurs r�servations
	 * @return une confirmation pour plusieurs r�servations
	 */
	public void afficherConfirmationMultiple() {
		System.out.println("\n"+ getProfesseur().getNom() +", vos réservations ont bien été effectuées.");
	}

	/**
	 * Renvoie la liste des cr�neaux disponibles 
	 * @param creneau : le cr�neau r�serv�
	 * @return les cr�neaux disponibles
	 */
	public String getCreneauxDisponibles(int creneau) {
		if ((creneau >= 0)&&(creneau <4)) {
			switch (creneau){
			case (0):{
				return "1:"+tabCreneaux[1]+", 2:"+tabCreneaux[2]+" et 3:"+tabCreneaux[3]+".";
			}
			case (1):{
				return "0:"+tabCreneaux[0]+", 2:"+tabCreneaux[2]+" et 3:"+tabCreneaux[3]+".";
			}
			case (2):{
				return "0:"+tabCreneaux[0]+", 1:"+tabCreneaux[1]+" et 3:"+tabCreneaux[3]+".";
			}
			case (3):{
				return "0:"+tabCreneaux[0]+", 1:"+tabCreneaux[1]+" et 2:"+tabCreneaux[2]+".";
			}
			}
		}
		return null;
	}

	

	/**
	 * Renvoie l'�tat de la r�servation
	 * @return l'�tat de la r�servation
	 */
	public boolean getEtatReservation() {
		return this.etatResa;
	}

	/**
	 * Fixe l'état de la réservation
	 * @param etat : l'état de la réservation
	 */
	public boolean setEtatReservation(boolean etat) {
		return this.etatResa = etat;
	}

	public Professeur getProfesseur() {
		return professeur;
	}

	public Seance getSeance() {
		return seance;
	}

	public static List<Reservation> getListeReservation() {
		return listeReservation;
	}

	public Salle getSalle() {
		return salle;
	}

	public void setListeReservation(List<Reservation> listeReservation) {
		// TODO Auto-generated method stub
		this.listeReservation=listeReservation;
	}
	
	
}